"""
针对users应用，定义的一些工具的模块
"""
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.conf import settings
from users.models import User
from meiduo_mall.utils.secret import SecretOAuth

# TODO: 多账号登陆方案二 ======自定义用户身份认证后端，实现多账号登陆验证=====
class UsernameMobileAuthBackend(ModelBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):
        """
        实现登陆验证 —— 验证用户名(账号)和密码
        :param request: 请求对象
        :param username: 账号，有可能是用户名，有可能是手机号，甚至有可能是邮箱
        :param password: 明文密码
        :return: 用户对象 或 None
        """

        # TODO: 自定义多账号验证逻辑
        try:
            # select * from tb_users where username='xxxxx' or mobile='xxxxxx';
            user = User.objects.get(
                Q(username=username) | Q(mobile=username)
            )
        except User.DoesNotExist as e:
            # 根据username或mobile都过滤不到用户对象，认证失败返回None
            return None

        # TODO：判定，如果是后台管理站点登陆，要求is_staff=True
        if request is None:
            if not user.is_staff:
                # 后台站点登陆，用户不是管理员，等同于身份认证失败
                return None

        if user.check_password(password):
            # 密码正确，认证成功，返回用户对象
            return user


# 构造邮箱激活链接
def generate_verify_email_url(request):
    """
    功能：构造邮箱激活链接
    :param request: 请求对象 --> 通过请求对象获取当前登陆的用户对象request.user
    :return: 返回完整的验证链接
    """

    user = request.user
    # 1、构造用户字典数据
    data = {'user_id': user.id, 'email': user.email}
    # 2、加密用户数据生成token值
    token = SecretOAuth().dumps(data)
    # 3、拼接完整的验证链接返回
    verify_url = settings.EMAIL_VERIFY_URL + token

    return verify_url


def jwt_response_payload_handler(token, user=None, request=None):
    """
    Returns the response data for both the login and refresh views.
    Override to return a custom response such as including the
    serialized representation of the User.

    Example:

    def jwt_response_payload_handler(token, user=None, request=None):
        return {
            'token': token,
            'user': UserSerializer(user, context={'request': request}).data
        }

    """
    return {
        'token': token,
        'username': user.username,
        'user_id': user.id
    }